{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b4916504-4477-47e1-b3f4-62f01b140bed",
   "metadata": {},
   "source": [
    "# 通义千问-基础知识点\n",
    "## DashScope 是平台，通义千问是模型，DashScope 是提供该模型服务的平台。\n",
    "可以在 DashScope 平台上调用通义千问的不同版本（如 Qwen-turbo、Qwen-plus、Qwen-max 等），用于文本生成、对话理解、代码编写等任务。\n",
    "\n",
    "| 名称 | 类型 | 关系 |\n",
    "|------|------|------|\n",
    "| **通义千问（Qwen）** | 大型语言模型 | 是 DashScope 平台上提供的核心模型之一 |\n",
    "| **DashScope** | 大模型服务平台 | 提供通义千问等模型的 API 接口和服务支持 |\n",
    "\n",
    "你可以把 DashScope 看作是一个“AI 工具箱”，而通义千问就是这个工具箱中最强大的“多功能瑞士军刀”。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f45ba8cd-b0bc-4839-9288-23b895d5b360",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "# Install the package\n",
    "%pip install --upgrade --quiet  dashscope"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "775d2b6f-6541-4bd0-88b2-be86a35ef5d6",
   "metadata": {},
   "source": [
    "## 获取通义千问API-KEY\n",
    "\n",
    "地址：https://bailian.console.aliyun.com/console?tab=model#/api-key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "632f70bc-e06f-4ec9-8a84-0b9139fcf9b3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      " ········\n"
     ]
    }
   ],
   "source": [
    "# Get a new token: https://help.aliyun.com/document_detail/611472.html?spm=a2c4g.2399481.0.0\n",
    "from getpass import getpass\n",
    "\n",
    "DASHSCOPE_API_KEY = getpass()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5f173bcc-2dff-4489-8b19-b72156c29f4f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"DASHSCOPE_API_KEY\"] = DASHSCOPE_API_KEY"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d27eff3-d580-4537-b9c8-8ea415c9ecf7",
   "metadata": {},
   "source": [
    "## ✅ 阿里大模型种类：\n",
    "\n",
    "- **最强纯文本模型（逻辑推理、复杂任务）：Qwen-Max**\n",
    "- **最强多模态模型（图文理解）：Qwen-VL-Max**\n",
    "- **综合性价比：Qwen-Plus**\n",
    "- **最快最便宜、轻量级任务首选：Qwen-Turbo**\n",
    "\n",
    "---\n",
    "\n",
    "## 🔍 各模型详细对比\n",
    "\n",
    "| 模型名称         | 类型           | 特点                                                                 | 适用场景                                               |\n",
    "|------------------|----------------|----------------------------------------------------------------------|--------------------------------------------------------|\n",
    "| **Qwen-Turbo**   | 文本大模型     | 响应速度快、成本低，适合轻量级任务                                    | 快速问答、简单文本生成、高并发场景                     |\n",
    "| **Qwen-Plus**    | 文本大模型     | 性能介于 Turbo 和 Max 之间，性价比高                                 | 中等复杂度任务，兼顾性能与成本                         |\n",
    "| **Qwen-Max**     | 文本大模型     | 推理能力最强，适合复杂、多步骤的任务                                | 高精度逻辑推理、复杂分析、专业领域问题                 |\n",
    "| **Qwen-VL-Max**  | 多模态大模型   | 支持图像 + 文本输入，图文理解能力最强（基于 Qwen-Max 文本能力增强） | 图文理解、视觉问答、文档分析、图像描述等多模态任务     |\n",
    "\n",
    "---\n",
    "\n",
    "## 📌 使用建议\n",
    "\n",
    "### 如果你只处理**纯文本任务**：\n",
    "- 最强：**Qwen-Max**\n",
    "- 性价比：**Qwen-Plus**\n",
    "- 最快最便宜：**Qwen-Turbo**\n",
    "\n",
    "### 如果你需要处理**图片+文字**（多模态任务）：\n",
    "- 只能选择：**Qwen-VL-Max**（目前唯一支持多模态的版本）\n",
    "\n",
    "---\n",
    "\n",
    "## 🎯 示例场景推荐\n",
    "\n",
    "| 场景                             | 推荐模型          |\n",
    "|----------------------------------|-------------------|\n",
    "| 聊天机器人、快速回复              | Qwen-Turbo        |\n",
    "| 内容总结、中等难度推理            | Qwen-Plus         |\n",
    "| 法律分析、深度编程、多轮逻辑推理  | Qwen-Max          |\n",
    "| 看图说话、PPT 分析、图文报告解析  | Qwen-VL-Max       |\n",
    "\n",
    "---\n",
    "\n",
    "如果你告诉我具体任务或用途，我可以帮你更准确地推荐用哪个模型最合适。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "88bbb961-7d6c-4e18-aabd-bb82debf5e1f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "chat resp: content='Hello' additional_kwargs={} response_metadata={} id='run--9c79e2da-6101-49c3-96fd-18c285d02151'\n",
      "chat resp: content='!' additional_kwargs={} response_metadata={} id='run--9c79e2da-6101-49c3-96fd-18c285d02151'\n",
      "chat resp: content=' How' additional_kwargs={} response_metadata={} id='run--9c79e2da-6101-49c3-96fd-18c285d02151'\n",
      "chat resp: content=' can I assist you' additional_kwargs={} response_metadata={} id='run--9c79e2da-6101-49c3-96fd-18c285d02151'\n",
      "chat resp: content=' today?' additional_kwargs={} response_metadata={} id='run--9c79e2da-6101-49c3-96fd-18c285d02151'\n",
      "chat resp: content='' additional_kwargs={} response_metadata={'finish_reason': 'stop', 'request_id': 'f2b1cf39-fca8-9868-85a2-caf456e4250a', 'token_usage': {'input_tokens': 9, 'output_tokens': 9, 'total_tokens': 18, 'prompt_tokens_details': {'cached_tokens': 0}}} id='run--9c79e2da-6101-49c3-96fd-18c285d02151'\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.chat_models.tongyi import ChatTongyi\n",
    "from langchain_core.messages import HumanMessage\n",
    "\n",
    "chatLLM = ChatTongyi(\n",
    "    streaming=True,\n",
    ")\n",
    "res = chatLLM.stream([HumanMessage(content=\"hi\")], streaming=True)\n",
    "for r in res:\n",
    "    print(\"chat resp:\", r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "83dcda69-07e0-4a98-9f48-30c60f9ae4b6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='私はプログラミングが好きです。', additional_kwargs={}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': 'e9de1e8e-b73d-9184-ad2b-6b2ddc6716f4', 'token_usage': {'input_tokens': 38, 'output_tokens': 8, 'total_tokens': 46, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--728ffac9-c7c7-49af-9bcf-079d42362475-0')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.messages import HumanMessage, SystemMessage\n",
    "\n",
    "messages = [\n",
    "    SystemMessage(\n",
    "        content=\"你是一位能把中文翻译成日文的得力助手。\"\n",
    "    ),\n",
    "    HumanMessage(\n",
    "        content=\"将这句话从中文翻译成日文。我喜欢编程。\"\n",
    "    ),\n",
    "]\n",
    "chatLLM.invoke(messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b68ae94b-06f6-4ff5-a5ac-bfef2074550b",
   "metadata": {},
   "source": [
    "## 工具调用（Tool Calling）  \n",
    "ChatTongyi 支持工具调用 API，该功能允许你描述工具及其参数，并让模型返回一个 JSON 对象，其中包含要调用的工具以及调用该工具所需的输入参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "83315036-f564-47ac-990d-147ba4fbd81c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='' additional_kwargs={'tool_calls': [{'function': {'name': 'multiply', 'arguments': '{\"first_int\": 5, \"second_int\": 42}'}, 'index': 0, 'id': 'call_3199a256de3849918fb01b', 'type': 'function'}]} response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'tool_calls', 'request_id': '2fc5beff-8be4-9a56-9356-2360da5cbdcb', 'token_usage': {'input_tokens': 179, 'output_tokens': 25, 'total_tokens': 204, 'prompt_tokens_details': {'cached_tokens': 0}}} id='run--56bcd921-bbd0-4699-9e17-89c81ea9a8ab-0' tool_calls=[{'name': 'multiply', 'args': {'first_int': 5, 'second_int': 42}, 'id': 'call_3199a256de3849918fb01b', 'type': 'tool_call'}]\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.chat_models.tongyi import ChatTongyi\n",
    "from langchain_core.tools import tool\n",
    "\n",
    "\n",
    "@tool\n",
    "def multiply(first_int: int, second_int: int) -> int:\n",
    "    \"\"\"Multiply two integers together.\"\"\"\n",
    "    return first_int * second_int\n",
    "\n",
    "\n",
    "llm = ChatTongyi(model=\"qwen-turbo\")\n",
    "\n",
    "llm_with_tools = llm.bind_tools([multiply])\n",
    "\n",
    "msg = llm_with_tools.invoke(\"5乘以42等于多少?\")\n",
    "\n",
    "print(msg)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcec9bfc-6660-4b83-8ff1-43240f25a1cc",
   "metadata": {},
   "source": [
    "### 生成式大语言模型本质就是“文字接龙”,它生成就是一段文字，没有办法调用程序/函数,所以content为空字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5ef4d701-6941-4e92-b402-8b6a94c295f4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='', additional_kwargs={'tool_calls': [{'function': {'name': 'multiply', 'arguments': '{\"first_int\": 5, \"second_int\": 42}'}, 'index': 0, 'id': 'call_3199a256de3849918fb01b', 'type': 'function'}]}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'tool_calls', 'request_id': '2fc5beff-8be4-9a56-9356-2360da5cbdcb', 'token_usage': {'input_tokens': 179, 'output_tokens': 25, 'total_tokens': 204, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--56bcd921-bbd0-4699-9e17-89c81ea9a8ab-0', tool_calls=[{'name': 'multiply', 'args': {'first_int': 5, 'second_int': 42}, 'id': 'call_3199a256de3849918fb01b', 'type': 'tool_call'}])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "msg"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b5e3840-fdd3-4f3b-a6ae-eb3e0dea8a9e",
   "metadata": {},
   "source": [
    "## 最简单的Agent智能体\n",
    "### 你需要手动提取 tool_call 中的信息，并调用对应的函数来执行任务："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "b7209da7-f4ec-47a4-b5e8-7964a06be264",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'first_int': 5, 'second_int': 42}\n",
      "调用工具 multiply，结果为: 210\n"
     ]
    }
   ],
   "source": [
    "# 假设 msg 是 AIMessage 对象\n",
    "for tool_call in msg.tool_calls:\n",
    "    tool_name = tool_call[\"name\"]\n",
    "    tool_args = tool_call[\"args\"]\n",
    "\n",
    "    if tool_name == \"multiply\":\n",
    "        print(tool_args)\n",
    "        result = multiply.invoke(tool_args)\n",
    "        print(f\"调用工具 {tool_name}，结果为: {result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a22cac76-5f1f-4f74-828c-afaff6af6220",
   "metadata": {},
   "source": [
    "### 如果你希望 LLM 在某些情况下直接给出回答而不是调用工具，可以尝试修改提示或问题形式，比如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "6d5c5d7f-cd0f-424d-a33d-fe6583adc0c1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "content='5乘以42的结果是210。' additional_kwargs={} response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': '042b0e0e-5d1e-97c1-a2a0-388e9e328bad', 'token_usage': {'input_tokens': 184, 'output_tokens': 11, 'total_tokens': 195, 'prompt_tokens_details': {'cached_tokens': 128}}} id='run--951866ec-5d28-45ae-8011-7db272ef4dc2-0'\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.chat_models.tongyi import ChatTongyi\n",
    "from langchain_core.tools import tool\n",
    "\n",
    "\n",
    "@tool\n",
    "def multiply(first_int: int, second_int: int) -> int:\n",
    "    \"\"\"Multiply two integers together.\"\"\"\n",
    "    return first_int * second_int\n",
    "\n",
    "\n",
    "llm = ChatTongyi(model=\"qwen-turbo\")\n",
    "\n",
    "llm_with_tools = llm.bind_tools([multiply])\n",
    "\n",
    "msg = llm_with_tools.invoke(\"5乘以42等于多少?请直接告诉我结果。\")\n",
    "\n",
    "print(msg)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5a5e18b-fe31-42fe-883e-0b01c77b4c14",
   "metadata": {},
   "source": [
    "### 手动构造参数  \n",
    "\n",
    "即：不依赖自动解析，而是由开发者或用户自行创建和填充调用工具所需的参数。这种方式通常用于调试、自定义逻辑或在某些框架功能受限时使用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a68f5327-13a3-488e-9303-660da2b6332c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='', additional_kwargs={'tool_calls': [{'function': {'name': 'get_current_weather', 'arguments': '{\"location\": \"天津市\"}'}, 'index': 0, 'id': 'call_469a2ee69a2c48fe9fb0f2', 'type': 'function'}]}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'tool_calls', 'request_id': '212ce296-598f-9bfb-a92f-c054bb782531', 'token_usage': {'input_tokens': 227, 'output_tokens': 18, 'total_tokens': 245, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--22e63040-e05c-458f-be30-d27d8fb6b4eb-0', tool_calls=[{'name': 'get_current_weather', 'args': {'location': '天津市'}, 'id': 'call_469a2ee69a2c48fe9fb0f2', 'type': 'tool_call'}])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_community.chat_models.tongyi import ChatTongyi\n",
    "from langchain_core.messages import HumanMessage, SystemMessage\n",
    "\n",
    "tools = [\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"get_current_time\",\n",
    "            \"description\": \"当你想知道现在的时间时非常有用。\",\n",
    "            \"parameters\": {},\n",
    "        },\n",
    "    },\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"get_current_weather\",\n",
    "            \"description\": \"当你想查询指定城市的天气时非常有用。\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"location\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"城市或县区，比如北京市、杭州市、余杭区等。\",\n",
    "                    }\n",
    "                },\n",
    "            },\n",
    "            \"required\": [\"location\"],\n",
    "        },\n",
    "    },\n",
    "]\n",
    "# 模拟工具函数的实际逻辑\n",
    "def get_current_weather(location: str):\n",
    "    # 这里你可以替换成真实的 API 调用\n",
    "    return f\"{location} 的天气是 18°C，晴天。\"\n",
    "\n",
    "def get_current_time():\n",
    "    import datetime\n",
    "    return str(datetime.datetime.now())\n",
    "    \n",
    "messages = [\n",
    "    SystemMessage(content=\"你是一位得力的助手。\"),\n",
    "    HumanMessage(content=\"天津的天气怎么样?\"),\n",
    "]\n",
    "chatLLM = ChatTongyi()\n",
    "llm_kwargs = {\"tools\": tools, \"result_format\": \"message\"}\n",
    "ai_message = chatLLM.bind(**llm_kwargs).invoke(messages)\n",
    "ai_message"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d9170716-e348-46ad-be0d-caea2e32b61b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "调用工具: get_current_weather，参数为: {'location': '天津市'}\n",
      "天气结果: 天津市 的天气是 18°C，晴天。\n"
     ]
    }
   ],
   "source": [
    "# 解析 tool_call\n",
    "if hasattr(ai_message, \"tool_calls\") and ai_message.tool_calls:\n",
    "    for tool_call in ai_message.tool_calls:\n",
    "        tool_name = tool_call[\"name\"]\n",
    "        tool_args = tool_call[\"args\"]\n",
    "    \n",
    "        print(f\"调用工具: {tool_name}，参数为: {tool_args}\")\n",
    "    \n",
    "        # 手动调用实际函数\n",
    "        if tool_name == \"get_current_weather\":\n",
    "            result = get_current_weather(**tool_args)\n",
    "            print(\"天气结果:\", result)\n",
    "        elif tool_name == \"get_current_time\":\n",
    "            result = get_current_time()\n",
    "            print(\"当前时间:\", result)\n",
    "else:\n",
    "    print(\"未调用任何工具，模型直接回复：\", ai_message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b750d93-0a7f-4a42-baeb-5f1c39b98319",
   "metadata": {},
   "source": [
    "### 部分模式（Partial Mode） \n",
    "该模式允许你从提供的初始文本开始，启用大模型继续生成后续内容。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "161beb26-f91d-4332-ab3a-e92b17edb35a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='你的目光总是穿透我，落在那遥不可及的天际？  \\n我的舞步跳得可美，却无人为我鼓掌，连回响也显得如此孤独。  \\n难道你很想天使问我？可她从未降临，只留下风中空洞的呢喃。  \\n\\n我的心事如丝线缠绕，挣脱不得，又似落叶飘零，无处安放。  \\n那些欢笑与泪水交织的夜晚，如今只剩记忆中的微光，在暗夜中闪烁又熄灭。  \\n我多想告诉你，这舞步背后藏着多少无声的痛楚，但话到嘴边，却化作一声叹息。  \\n\\n或许，我只是你生命里的过客；而我，却将你的影子镌刻在心底，再也无法抹去。', additional_kwargs={}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'stop', 'request_id': '53cc7672-e239-9d12-a5ec-752de7ef4588', 'token_usage': {'input_tokens': 42, 'output_tokens': 167, 'total_tokens': 209, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--4287c5c9-e099-42be-a60c-16017015ec8f-0')"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_community.chat_models.tongyi import ChatTongyi\n",
    "from langchain_core.messages import AIMessage, HumanMessage\n",
    "\n",
    "messages = [\n",
    "    HumanMessage(\n",
    "        content=\"\"\"请接续“难道你很想天使问我? 我的舞步跳得可美”这句话，表达情感的复杂和作者的伤感之情。\"\"\"\n",
    "    ),\n",
    "    AIMessage(\n",
    "        content=\"为何\", additional_kwargs={\"partial\": True}\n",
    "    ),\n",
    "]\n",
    "chatLLM = ChatTongyi()\n",
    "ai_message = chatLLM.invoke(messages)\n",
    "ai_message"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8292ff6-6a7a-4ae5-8687-0301b92065ea",
   "metadata": {},
   "source": [
    "## 通义千问与视觉能力 \n",
    "Qwen-VL（qwen-vl-plus / qwen-vl-max）是支持图像处理的模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "263e8744-f87d-4e27-bcbd-51dd23b78f0c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content=[{'text': '这张图展示了Windows操作系统的“控制面板”中的“程序和功能”设置页面，具体是“启用或关闭 Windows 功能”的窗口。\\n\\n### 1. 左侧导航栏\\n- **控制面板主页**：提供访问控制面板中所有设置的入口。\\n- **系统和安全**、**网络和 Internet**、**硬件和声音**、**程序**、**用户账户**、**外观和个性化**、**时钟和区域**、**轻松使用**：这些都是控制面板中的主要分类选项。\\n\\n### 2. 中间部分\\n- **程序和功能**：这是当前选中的选项，显示了与程序管理相关的功能。\\n- **卸载程序**：允许用户卸载已安装的程序。\\n- **启用或关闭 Windows 功能**：这是当前打开的功能，允许用户启用或禁用特定的Windows功能。\\n- **运行行为以前版本的 Windows 编写的程序**：提供兼容性设置，以便运行旧版程序。\\n- **默认程序**：允许用户更改媒体或设备的默认设置。\\n- **Java**：显示了Java的相关信息。\\n\\n### 3. 右侧窗口 - 启用或关闭 Windows 功能\\n- **标题**：启用或关闭 Windows 功能。\\n- **说明**：若要启用一种功能，请选择其复选框。若要关闭一种功能，请清除其复选框。填充的框表示仅启用该功能的一部分。\\n\\n### 4. 特别标注的部分\\n- **黄色圆圈标注**：\\n  - **Virtual Machine Platform**（虚拟机平台）：已被选中，表示该功能已启用。\\n  - **Windows 虚拟机监控程序平台**：已被选中，表示该功能已启用。\\n  - **Windows TIFF IFilter**：未被选中，表示该功能未启用。\\n\\n- **黄色线条标注**：\\n  - **启用或关闭 Windows 功能**：强调了当前打开的功能页面。\\n\\n### 5. 其他功能选项\\n- **.NET Framework 3.5 (包括 .NET 2.0 和 3.0)**、**.NET Framework 4.8 Advanced Services**、**Internet Information Services** 等：这些都是可选的Windows功能，用户可以根据需要进行启用或禁用。\\n\\n### 6. 底部按钮\\n- **确定**：点击以保存所做的更改。\\n- **取消**：点击以放弃更改并关闭窗口。\\n\\n### 总结\\n这张图主要展示了如何在Windows操作系统中通过“控制面板”来启用或禁用特定的功能，特别标注了“Virtual Machine Platform”和“Windows 虚拟机监控程序平台”这两个功能已被启用，而“Windows TIFF IFilter”未被启用。这对于需要配置特定功能（如虚拟机支持）的用户非常有用。'}], additional_kwargs={}, response_metadata={'model_name': 'qwen-vl-max', 'finish_reason': 'stop', 'request_id': '6af9c560-d67b-9c3f-b5ff-4c9e0faf7410', 'token_usage': {'input_tokens': 1231, 'output_tokens': 598, 'input_tokens_details': {'text_tokens': 11, 'image_tokens': 1220}, 'total_tokens': 1829, 'output_tokens_details': {'text_tokens': 598}, 'image_tokens': 1220, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='run--e0a64f78-0f84-4fc9-9fc3-aed02be2a754-0')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_community.chat_models import ChatTongyi\n",
    "from langchain_core.messages import HumanMessage\n",
    "\n",
    "chatLLM = ChatTongyi(model_name=\"qwen-vl-max\")\n",
    "image_message = {\n",
    "    \"image\": \"https://gitee.com/hellowoody/openharmony-hint/raw/main/assets/imgs/wsl-setting.png\",\n",
    "}\n",
    "text_message = {\n",
    "    \"text\": \"描述这张图\",\n",
    "}\n",
    "message = HumanMessage(content=[text_message, image_message])\n",
    "res = chatLLM.invoke([message])\n",
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "cf7facd1-3f72-471a-9287-ed72215714f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这张图展示了Windows操作系统的“控制面板”中的“程序和功能”设置页面，具体是“启用或关闭 Windows 功能”的窗口。\n",
      "\n",
      "### 1. 左侧导航栏\n",
      "- **控制面板主页**：提供访问控制面板中所有设置的入口。\n",
      "- **系统和安全**、**网络和 Internet**、**硬件和声音**、**程序**、**用户账户**、**外观和个性化**、**时钟和区域**、**轻松使用**：这些都是控制面板中的主要分类选项。\n",
      "\n",
      "### 2. 中间部分\n",
      "- **程序和功能**：这是当前选中的选项，显示了与程序管理相关的功能。\n",
      "- **卸载程序**：允许用户卸载已安装的程序。\n",
      "- **启用或关闭 Windows 功能**：这是当前打开的功能，允许用户启用或禁用特定的Windows功能。\n",
      "- **运行行为以前版本的 Windows 编写的程序**：提供兼容性设置，以便运行旧版程序。\n",
      "- **默认程序**：允许用户更改媒体或设备的默认设置。\n",
      "- **Java**：显示了Java的相关信息。\n",
      "\n",
      "### 3. 右侧窗口 - 启用或关闭 Windows 功能\n",
      "- **标题**：启用或关闭 Windows 功能。\n",
      "- **说明**：若要启用一种功能，请选择其复选框。若要关闭一种功能，请清除其复选框。填充的框表示仅启用该功能的一部分。\n",
      "\n",
      "### 4. 特别标注的部分\n",
      "- **黄色圆圈标注**：\n",
      "  - **Virtual Machine Platform**（虚拟机平台）：已被选中，表示该功能已启用。\n",
      "  - **Windows 虚拟机监控程序平台**：已被选中，表示该功能已启用。\n",
      "  - **Windows TIFF IFilter**：未被选中，表示该功能未启用。\n",
      "\n",
      "- **黄色线条标注**：\n",
      "  - **启用或关闭 Windows 功能**：强调了当前打开的功能页面。\n",
      "\n",
      "### 5. 其他功能选项\n",
      "- **.NET Framework 3.5 (包括 .NET 2.0 和 3.0)**、**.NET Framework 4.8 Advanced Services**、**Internet Information Services** 等：这些都是可选的Windows功能，用户可以根据需要进行启用或禁用。\n",
      "\n",
      "### 6. 底部按钮\n",
      "- **确定**：点击以保存所做的更改。\n",
      "- **取消**：点击以放弃更改并关闭窗口。\n",
      "\n",
      "### 总结\n",
      "这张图主要展示了如何在Windows操作系统中通过“控制面板”来启用或禁用特定的功能，特别标注了“Virtual Machine Platform”和“Windows 虚拟机监控程序平台”这两个功能已被启用，而“Windows TIFF IFilter”未被启用。这对于需要配置特定功能（如虚拟机支持）的用户非常有用。\n"
     ]
    }
   ],
   "source": [
    "print(res.content[0][\"text\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "0bc5fc4b-4536-4fe9-8c5d-b9321771b028",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ChatTongyi(client=<class 'dashscope.aigc.multimodal_conversation.MultiModalConversation'>, model_name='qwen-vl-max', model_kwargs={}, dashscope_api_key=SecretStr('**********'))"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chatLLM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b2c3ab1-414d-40a3-9103-ebc79b2bce86",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
